<?php
/**
 * This file defines the class {@see \BF\IO\Path}
 *
 * @author     Kado <ulfikado@gmail.com>
 * @category   Beluga PHP5.3+ Framework
 * @package    BF\IO
 * @since      2015-01-31 00:29
 * @subpackage Core
 * @version    0.1
 */

namespace BF\IO
{

   /**
    * A static path helper class
    *
    * @since      v0.1
    */
   class Path
   {

      # <editor-fold defaultstate="collapsed" desc=" - - -   P U B L I C   S T A T I C   F I E L D S   - - - - - - - - - - - - - - - -">

      /**
       * This directory separator is not used by current system.
       *
       * @var string
       */
      public static $NoFolderSeparator;

      # </editor-fold>

      # <editor-fold defaultstate="collapsed" desc=" - - >   P R I V A T E   C O N S T R U C T O R   - - - - - - - - - - - - - - - - -">

      /**
       * Inits a new instance.
       */
      private function __construct() { }

      # </editor-fold>

      # <editor-fold defaultstate="collapsed" desc=" - - -   P U B L I C   S T A T I C   M E T H O D S   - - - - - - - - - - - - - - -">

      /**
       * Combine 2 or 3 path elements to a single path and returns it.
       *
       * @param  string $basepath The base path.
       * @param  string $next1    The 2nd path part.
       * @param  string $next2    Optional 3rd path part
       * @return string
       */
      public static function Combine( $basepath, $next1, $next2 = null )
      {
         if ( empty( $next2 ) )
         {
            return (
               \rtrim( $basepath, "\r\n\t /\\" )
                  . \DIRECTORY_SEPARATOR
                  . \ltrim( $next1, "\r\n\t /\\" )
            );
         }
         return (
            \rtrim( $basepath, "\r\n\t /\\" )
               . \DIRECTORY_SEPARATOR
               . \trim( $next1, "\r\n\t /\\" )
               . \DIRECTORY_SEPARATOR
               . \ltrim( $next2, "\r\n\t /\\" )
          );
      }

      /**
       * Normalizes a path to directory separators, used by current system.
       *
       * @param  string $path
       * @return string
       */
      public static function Normalize( $path )
      {
         if ( empty( self::$NoFolderSeparator ) )
         {
            self::$NoFolderSeparator = \IS_WIN ? '/' : '\\';
         }
         $tmpPath = ( \IS_WIN
            ? \trim(
               \str_replace(
                  self::$NoFolderSeparator,
                  \DIRECTORY_SEPARATOR,
                  $path
               ),
               \DIRECTORY_SEPARATOR
            )
            : \rtrim(
               \str_replace(
                  self::$NoFolderSeparator,
                  \DIRECTORY_SEPARATOR,
                  $path
               ),
               \DIRECTORY_SEPARATOR
            )
         );
         // return the resulting path and replace /./ or \.\ with a single directory separator
         return str_replace(
            \DIRECTORY_SEPARATOR . '.' . \DIRECTORY_SEPARATOR,
            \DIRECTORY_SEPARATOR,
            $tmpPath
         );
      }

      /**
       * Returns if the defined path is a absolute path definition.
       *
       * @param  string  $path
       * @param  boolean $dependToOS
       * @return boolean
       */
      public static function IsAbsolute( $path, $dependToOS = true )
      {
         if ( \is_null( $path ) || \strlen( $path ) < 1 )
         {
            return false;
         }
         if ( $dependToOS )
         {
            if ( ! \IS_WIN )
            {
               return $path[ 0 ] == '/';
            }
            if ( \strlen( $path ) < 2 )
            {
               return false;
            }
            return $path[ 1 ] == ':' || ( $path[ 0 ] == '\\' && $path[ 1 ] == '\\' );
         }
         return $path[ 0 ] == '/' || $path[ 1 ] == ':' || ( $path[ 0 ] == '\\' && $path[ 1 ] == '\\' );
      }

      /**
       * Switches als windows directory separaot (backslashes) to unix like (slashes)
       *
       * @param  string $path
       * @return string
       */
      public static function Unixize( $path )
      {
         if ( \is_null( $path ) )
         {
            return '';
         }
         return \str_replace( '\\', '/', $path );
      }

      /**
       * Removes the current working directory from defined path, if it starts with it.
       *
       * @param  string $path
       * @return string
       */
      public static function RemoveWorkingDir( $path )
      {
         if ( \is_null( $path ) )
         {
            return '';
         }
         $wd = '~^' . \preg_quote( self::Unixize( \getcwd() ) . '/' ) . '~';
         return \preg_replace( $wd, '', self::Unixize( $path ) );
      }

      /**
       * This is a multibyte safe pathinfo() replacement.
       *
       * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe.
       * Works similarly to the one in PHP >= 5.2.0
       *
       * @link http://www.php.net/manual/en/function.pathinfo.php#107461
       *
       * @param  string         $path     A filename or path, does not need to exist as a file
       * @param  integer|string $infoType Either a PATHINFO_* constant, or a string name to return only the specified
       *                                  piece, allows 'filename' to work on PHP < 5.2
       * @return string|array
       */
      public static function GetPathinfo( $path, $infoType = null )
      {
         $infos = array( 'dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '' );
         $pathinfo = array();
         if ( preg_match( '%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo ) )
         {
            if ( array_key_exists( 1, $pathinfo ) )
            {
               $infos[ 'dirname' ]   = $pathinfo[ 1 ];
            }
            if ( array_key_exists( 2, $pathinfo ) )
            {
               $infos[ 'basename' ]  = $pathinfo[ 2 ];
            }
            if ( array_key_exists( 5, $pathinfo ) )
            {
               $infos[ 'extension' ] = $pathinfo[ 5 ];
            }
            if ( array_key_exists( 3, $pathinfo ) )
            {
               $infos[ 'filename' ]  = $pathinfo[ 3 ];
            }
         }
         switch ( $infoType )
         {
            case PATHINFO_DIRNAME:
            case 'dirname':
               return $infos[ 'dirname' ];
            case PATHINFO_BASENAME:
            case 'basename':
               return $infos[ 'basename' ];
            case PATHINFO_EXTENSION:
            case 'extension':
               return $infos[ 'extension' ];
            case PATHINFO_FILENAME:
            case 'filename':
               return $infos[ 'filename' ];
            default:
               return $infos;
         }

      }

      # </editor-fold>

   }

}

